home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 January / Macworld (1998-01).dmg / Shareware World / Comms & Internet / HTML mode 2.0 etc. / cssMode.tcl next >
Text File  |  1997-09-22  |  13KB  |  423 lines

  1. ## -*-Tcl-*-
  2.  # ###################################################################
  3.  #  CSS mode - tools for editing CSS documents
  4.  # 
  5.  #  FILE: "cssMode.tcl"
  6.  #                                    created: 97-03-01 17.02.41 
  7.  #                                last update: 97-09-20 19.27.54 
  8.  #  Author: Johan Linde
  9.  #  E-mail: <jl@theophys.kth.se>
  10.  #     www: <http://bach.theophys.kth.se/~jl/Alpha.html>
  11.  #  
  12.  # Version: 1.0
  13.  # 
  14.  # Copyright 1997 by Johan Linde
  15.  #  
  16.  # This software may be used freely, and distributed freely, as long as the 
  17.  # receiver is not obligated in any way by receiving it.
  18.  #  
  19.  # If you make improvements to this file, please share them!
  20.  # 
  21.  # ###################################################################
  22.  ##
  23.  
  24. # Defining CSS mode
  25.  
  26. if {$startingUp} {
  27.     addMode CSS cssMenu {*.css *.CSS} cssMenu
  28.     addMenu cssMenu
  29.     set cssMenu CSS
  30. #     set cssMenu •150
  31.     return
  32. }
  33.  
  34. proc cssMenu {} {}
  35.  
  36. # ◊◊◊◊ Change below for new system §9 ◊◊◊◊ #
  37.  
  38. newModeVar CSS wordWrap 0 1
  39. newModeVar CSS wordBreak {\w+} 0
  40. newModeVar CSS wordBreakPreface {\W} 0
  41. newModeVar CSS commentColor red    0
  42. newModeVar CSS keywordColor blue 0
  43. newModeVar CSS htmlColor magenta 0
  44. newModeVar CSS elecRBrace 1 1
  45. newModeVar CSS elecLBrace 1 1
  46. newModeVar CSS electricSemi 1 1
  47. newModeVar CSS openNonTextFile 1 1
  48.  
  49. # ◊◊◊◊ end changing for new system §9 ◊◊◊◊ #
  50.  
  51. # Coloring
  52. proc cssColoring {} {
  53.     global CSSmodeVars
  54.     regModeKeywords -b {/*} {*/} -c $CSSmodeVars(commentColor) -k $CSSmodeVars(keywordColor) CSS {
  55.     font-family font-style font-variant font-weight font-size font 
  56.     color background-color background-image background-repeat background-attachment
  57.     background-position background word-spacing letter-spacing text-decoration
  58.     vertical-align text-transform text-align text-indent line-height
  59.     margin-top margin-right margin-bottom margin-left margin padding-top padding-right
  60.     padding-bottom padding-left padding border-top-width border-right-width
  61.     border-bottom-width border-left-width border-width border-color border-style
  62.     border-top border-right border-bottom border-left border width height float clear
  63.     display white-space list-style-type list-style-image list-style-position list-style
  64.     @import important
  65.     link visited active first-letter first-line}
  66.     regModeKeywords -a -k $CSSmodeVars(htmlColor) CSS [cssGetHtmlWords]
  67. }
  68.  
  69. # Load other CSS mode files.
  70. foreach tmp {hctsmsl hctsmslShared hctsmslMenu} {
  71.     if {[info exists htmlModeIsLoaded] && ($tmp == "hctsmslMenu" || $tmp == "hctsmslShared")} {continue}
  72.     if {$tmp == "hctsmsl" && [info exists cssUnits]} {continue}
  73.     if { [catch {${tmp}.tcl}] } {
  74.         beep
  75.         alertnote "Loading of ${tmp}.tcl failed"
  76.         return
  77.     }
  78. }
  79.  
  80. # Clean up after version 1.0b1
  81. if {[info exists htmlMenuKey]} {
  82.     foreach tmp [array names htmlMenuKey] {
  83.         removeArrDef htmlMenuKey $tmp
  84.     }
  85.     htmlWriteMenuKeys
  86. }
  87.  
  88. proc cssHTMLelement {elem} {
  89.     insertText $elem
  90. }
  91.  
  92. # ◊◊◊◊ Change below for new system §10 ◊◊◊◊ #
  93. proc CSSindentLine {} {
  94.     CindentLine
  95. }
  96. # ◊◊◊◊ end changing for new system §10 ◊◊◊◊ #
  97.  
  98. proc CSSDividingLine {} {
  99.     insertText "/*=============================================================================*/\r"
  100. }
  101. bind 'l' <C> CSSDividingLine CSS
  102.  
  103.  
  104. # ◊◊◊◊ Change below for new system §17 ◊◊◊◊ #
  105. proc CSScarriageReturn {} {
  106.     HTMLcarriageReturn
  107. }
  108. # ◊◊◊◊ end changing for new system §17 ◊◊◊◊ #
  109.  
  110. proc CSSelectricSemi {} {
  111.     global CSSmodeVars
  112.     if {[isSelection]} {deleteSelection}
  113.     if {$CSSmodeVars(electricSemi)} {
  114.         insertText ";\r"
  115.         CindentLine
  116.     } else {
  117.         insertText ";"
  118.     }
  119. }
  120.  
  121. proc parseFuncsCSS {} {
  122.     set pos 0
  123.     set funcExpr {^[ \t]*([^\r\{]+)\{}
  124.     while {[set res [search -s -f 1 -r 1 -i 0 -n $funcExpr $pos]] != ""} {
  125.         if {[regexp $funcExpr [getText [car $res] [cadr $res]] dummy word]} {
  126.             lappend m [list $word [car $res]]
  127.         }
  128.         set pos [cadr $res]
  129.     }
  130.     return [join [lsort -ignore $m]]
  131. }
  132.  
  133. #===============================================================================
  134. # Key bindings
  135. #===============================================================================
  136.  
  137. # Define key bindings from html menu.
  138. proc cssBindingsFromMenu {me tmplist} {
  139.     global htmlMenuKey html${me}Sub
  140.     upvar $tmplist tmp
  141.     foreach it [set html${me}Sub] {
  142.         if {[llength $it] > 2} {
  143.             set elem [lindex $it 2]            
  144.              if {[info exists htmlMenuKey(${me}/[lindex $it 1])]} {
  145.                 set key $htmlMenuKey(${me}/[lindex $it 1])
  146.             } else {
  147.                 set key [lindex $it 0]
  148.             }
  149.             cssBindOneKey $key $elem "" tmp
  150.         }
  151.     }
  152. }
  153.  
  154. proc cssBindOneKey {key elem {un ""} {tmplist ""}} {
  155.      set funcKeys {Enter 0x0d 0x09 Clear F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
  156.      Help 0x08 Del Home End Pgup Pgdn}
  157.  
  158.     set mods ""
  159.     if {[regexp {<B} $key]} {append mods z}
  160.     if {[regexp {<I} $key]} {append mods o}
  161.     if {[regexp {<U} $key]} {append mods s}
  162.     if {[regexp {<O} $key]} {append mods c}
  163.     set key1 ""
  164.     if {[regexp {/(.)} $key a b]} {
  165.         if {[string compare $b a] == -1 || [string compare $b z] == 1} {
  166.             set key1 '[string tolower $b]'
  167.         } else {
  168.             set key1 [lindex $funcKeys [expr [htmlAscii $b] - 97]]
  169.         }
  170.     }
  171.     if {$key1 == ""} {return}
  172.     if {[string range $key1 0 1] == "0x"} {
  173.         set cmd ${un}ascii
  174.     } else {
  175.         set cmd ${un}bind
  176.     }
  177.     eval [list $cmd $key1 <$mods> "cssHTMLelement $elem" CSS]
  178.     if {$tmplist != ""} {
  179.         upvar $tmplist tmp
  180.         append tmp [list $cmd $key1 <$mods> "cssHTMLelement $elem" CSS] \r
  181.     }
  182. }
  183.  
  184. # Redefine key bindings when changed in HTML menu.
  185. proc cssReBindKey {meny keyItems} {
  186.     global html${meny}Sub
  187.     set items [set html${meny}Sub]
  188.     foreach it $keyItems {
  189.         set it0 [lindex $it 0]
  190.         foreach it1 $items {
  191.             if {[lindex $it1 1] == $it0} {
  192.                 set elem [lindex $it1 2]
  193.                 break
  194.             }
  195.         }
  196.         # Skip those which aren't html elements
  197.         if {[llength $it1] < 3} {continue}
  198.         cssBindOneKey [lindex $it 1] $elem un
  199.         cssBindOneKey [lindex $it 2] $elem
  200.     }
  201. }
  202.  
  203. proc cssMenuKeys {} {
  204.     global htmlMenuKey
  205.     set rebuildCSS 0
  206.     set somethingModified 0
  207.     htmlReadMenuKeys
  208.     htmlSetKeysInMenu CSS
  209.     if {$somethingModified} {htmlWriteMenuKeys}
  210.     catch {unset htmlMenuKey}
  211.     if {$rebuildCSS} {cssRebuildMenu}
  212. }
  213.  
  214. #===============================================================================
  215. # Menu handling
  216. #===============================================================================
  217.  
  218. set htmlCSSSub [concat [lrange $htmlStyleSub 3 end] {"(-" {"<O<U/S" "Reload in Browser"} {"<O/c" "Word Complete"} {"" "Colors…"} {"" "Key Bindings…"} {"" "Preferences…"}}]
  219.  
  220. proc cssBuildMenu {} {
  221.     global cssMenu htmlMenuKey
  222.     if {[catch {htmlReadCache "CSS menu cache" css}]} {
  223.         htmlReadMenuKeys
  224.         set me [htmlBuildOneMenu CSS]
  225.         menu -M CSS -p cssMenuItem -m -n $cssMenu $me
  226.         set h {menu -M CSS -p cssMenuItem -m -n $cssMenu}
  227.         lappend h $me
  228.         htmlSaveCache "CSS menu cache" $h css
  229.     }
  230.     catch {unset htmlMenuKey}
  231. }
  232.  
  233. proc cssRebuildMenu {} {
  234.     htmlDeleteCache "CSS menu cache"
  235.     cssBuildMenu
  236. }
  237.  
  238. proc cssMenuItem {menu item} {
  239.     switch $item {
  240.         "Reload in Browser" {cssReloadinBrowser}
  241.         "Word Complete" {cssWordComplete}
  242.         Colors {htmlColors}
  243.         "Key Bindings" {cssMenuKeys}
  244.         "Preferences" {CSSmodifyFlags}
  245.         Import {cssDialog @import}
  246.         Display {cssDialog Display}
  247.         default {cssDialog [join [string tolower $item] -]}
  248.     }
  249. }
  250.  
  251. #===============================================================================
  252. # Cmd-double-click
  253. #===============================================================================
  254.  
  255. proc CSSDblClick {from to} {
  256.     HTMLDblClick $from $to
  257. }
  258.  
  259. #===============================================================================
  260. # Reload in Browser
  261. #===============================================================================
  262.  
  263. proc cssReloadinBrowser {} {
  264.     global browserSig HTMLmodeVars
  265.     if {$browserSig != "MOSS" && $browserSig != "MSIE"} {
  266.         beep; message "Works only with Netscape and MSIE."; return
  267.     }
  268.     # returns window ids
  269.     if {![regexp {\[([0-9]+)} [AEBuild -r '$browserSig' WWW! LSTW] dum winnum]} {beep; message "No browser window."; return}
  270.     if {[winDirty]} {
  271.         if {[set ask [askyesno -c "Save '[lindex [winNames] 0]'?"]] == "yes"} {
  272.             save
  273.         } elseif {$ask == "cancel"} {
  274.             return
  275.         }
  276.     }
  277.     # returns window info
  278.     regexp {\[([^ ]+)} [AEBuild -r '$browserSig' WWW! WNFO ---- $winnum] dum winurl
  279.     set winurl [string trim $winurl "“”,"]
  280.     if {$winurl == "'TEXT'()"} {beep; message "Empty browser window."; return}
  281.     # reloads window
  282.     set flgs ""
  283.     if {$browserSig == "MSIE"} {set flgs "FLGS 1"}
  284.     eval AEBuild '$browserSig' WWW! OURL ---- "“$winurl”" $flgs
  285.     if {![info exists HTMLmodeVars(browseInForeground)] || $HTMLmodeVars(browseInForeground)} {switchTo '$browserSig'}
  286. }
  287.  
  288.  
  289. #===============================================================================
  290. # Preferences
  291. #===============================================================================
  292.  
  293. proc CSSmodifyFlags {} {
  294.     global CSSmodeVars modifiedModeVars colorInds
  295.     set colors {none blue cyan green magenta red white yellow}
  296.     foreach c [lsort [array names colorInds]] {
  297.         if {[regexp {color} $c]} {lappend colors $c}
  298.     }
  299.     set box "-t {CSS mode Preferences} 100 10 450 30 \
  300.     -c {Electric left braces} $CSSmodeVars(elecLBrace) 10 35 450 50 \
  301.     -c {Electric right braces} $CSSmodeVars(elecRBrace) 10 55 450 70 \
  302.     -c {Electric semicolon} $CSSmodeVars(electricSemi) 10 75 450 90 \
  303.     -c {Cmd-double-clicking on non-text file link opens file} $CSSmodeVars(openNonTextFile) 10 95 450 110 \
  304.     -t {Color of keywords:} 10 115 150 130 \
  305.     -m [list [concat $CSSmodeVars(keywordColor) $colors]] 160 115 310 135 \
  306.     -t {Color of comments:} 10 140 150 155 \
  307.     -m [list [concat $CSSmodeVars(commentColor) $colors]] 160 140 310 155 \
  308.     -t {Color of HTML:} 10 165 150 180 \
  309.     -m [list [concat $CSSmodeVars(htmlColor) $colors]] 160 165 310 180 \
  310.     -t wordBreak: 10 190 150 205 \
  311.     -e [list $CSSmodeVars(wordBreak)] 155 190 450 205 \
  312.     -t wordBreakPreface: 10 215 150 230 \
  313.     -e [list $CSSmodeVars(wordBreakPreface)] 155 215 450 230"
  314.     set values [eval [concat dialog -w 460 -h 275 -b OK 20 245 85 265 -b Cancel 110 245 175 265 $box]]
  315.     if {[lindex $values 1]} {return}
  316.     set i 1
  317.     foreach flag {elecLBrace elecRBrace electricSemi openNonTextFile keywordColor
  318.     commentColor htmlColor wordBreak wordBreakPreface} {
  319.         global $flag
  320.         incr i
  321.         set val [lindex $values $i]
  322.         if {$CSSmodeVars($flag) != $val} {
  323.             set $flag $val
  324.             set CSSmodeVars($flag) $val
  325.             lappend modifiedModeVars [list $flag CSSmodeVars]
  326.             if {[string match "*Color" $flag]} {cssColoring}
  327.         }
  328.     }
  329.     
  330.     
  331. }
  332.  
  333. #===============================================================================
  334. # Initialization
  335. #===============================================================================
  336.  
  337. set cssVersion 2.0
  338.  
  339. # Define key bindings.
  340. if {[catch {htmlReadCache "CSS keybindings cache" css}]} {
  341.     htmlReadMenuKeys
  342.     message "Defining key bindings…"
  343.     foreach tmp [lrange $htmlSubMenus $htmlStartElements end] {
  344.         cssBindingsFromMenu [lindex $tmp 0] tmplist
  345.     }
  346.     if {[info exists htmlModeIsLoaded]} {
  347.         foreach tmp [array names htmlElemKeyBinding] {
  348.             cssBindOneKey $htmlElemKeyBinding($tmp) $tmp "" tmplist
  349.         }
  350.     } elseif {[file exists $PREFS:HTMLadditions.tcl]} {
  351.         set tmpcid [scancontext create]
  352.         scanmatch $tmpcid {htmlElemKeyBinding} {
  353.             cssBindOneKey [lindex [lindex $matchInfo(line) 1] 2] [lindex $matchInfo(line) 0] "" tmplist
  354.         }
  355.         if {![catch {open $PREFS:HTMLadditions.tcl} tmpfid]} {
  356.             scanfile $tmpcid $tmpfid
  357.             close $tmpfid
  358.         }
  359.         scancontext delete $tmpcid
  360.         catch {unset tmpcid tmpfid}
  361.     }
  362.     htmlSaveCache "CSS keybindings cache" $tmplist css
  363.     unset tmplist
  364.     catch {unset htmlMenuKey}
  365. } else {
  366.     message "Reading key bindings…"
  367. }
  368.  
  369. if {![info exists htmlModeIsLoaded]} {
  370.     set cssHtmlWords {A ADDRESS APPLET AREA B BASE BASEFONT BGSOUND BIG 
  371.         BLINK BLOCKQUOTE BODY BR 
  372.         CAPTION CENTER CITE CODE COL COLGROUP DD DFN DIR DIV DL DT EM EMBED FONT 
  373.         FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME ILAYER IMG INPUT ISINDEX KBD 
  374.         KEYGEN LAYER LI LINK MAP MARQUEE MENU META MULTICOL NOBR NOEMBED NOFRAMES NOLAYER NOSCRIPT 
  375.         OBJECT OL OPTION P PARAM PRE SAMP SCRIPT SELECT SMALL SPACER SPAN STRIKE 
  376.         STRONG STYLE SUB SUP TABLE TBODY TD TEXTAREA TFOOT TH THEAD TITLE TR TT U 
  377.         UL VAR WBR}
  378.     if {[file exists $PREFS:HTMLadditions.tcl]} {
  379.         set tmpcid [scancontext create]
  380.         scanmatch $tmpcid {htmlElemKeyBinding} {
  381.             lappend cssHtmlWords [lindex $matchInfo(line) 0]
  382.         }
  383.         if {![catch {open $PREFS:HTMLadditions.tcl} tmpfid]} {
  384.             scanfile $tmpcid $tmpfid
  385.             close $tmpfid
  386.         }
  387.         scancontext delete $tmpcid
  388.         catch {unset tmpcid tmpfid}
  389.     }
  390. }
  391.  
  392. cssColoring
  393. cssBuildMenu
  394. unset tmp
  395. rename cssBindingsFromMenu ""
  396.  
  397. # ◊◊◊◊ Change below for new system §11 ◊◊◊◊ #
  398.  
  399. if {[info commands useUniversalCompletions] == ""} {
  400.     # No Vince's Additions
  401.     bind '\{' <s> electricLeft    CSS
  402.     bind '\}' <s> electricRight    CSS
  403.     bind '\;'  CSSelectricSemi CSS
  404.     bind '\r' CSScarriageReturn CSS
  405. } else {
  406.     # Vince's Additions
  407.     set commentCharacters(CSS:General) "/*"
  408.     set commentCharacters(CSS:Paragraph) [list "/* " " */" " * "]
  409.     set commentCharacters(CSS:Box) [list "/*" 2 "*/" 2 "*" 3]
  410. }
  411.  
  412. # ◊◊◊◊ end changing for new system §11 ◊◊◊◊ #
  413.  
  414. if {[info exists htmlModeIsLoaded] && $htmlVersion != $cssVersion} {
  415.     alertnote "Warning: The versions of HTML mode and CSS mode may not be compatible.\
  416.         Always install new versions of HTML mode and CSS mode simultaneously."
  417. }
  418.  
  419. set cssModeIsLoaded 1
  420.  
  421. message "CSS initialization complete."
  422.  
  423.